﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Microsoft.Win32;
using NLog;
using SellAvi.Classes;
using SellAvi.Model;
using SellAvi.Properties;
using SellAvi.Services;
using SellAvi.Views;
using SHDocVw;

namespace SellAvi.ViewModel
{
    public class EditProductViewModel : ViewModelBase
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
        public static RelayCommand<AvitoProduct> MarkProductCommand { get; set; }
        public static RelayCommand<AvitoImage> PhotoSelectionChangedCommand { get; set; }
        public static RelayCommand NextProductCommand { get; set; }
        public static RelayCommand PrevProductCommand { get; set; }
        public static RelayCommand SaveProductCommand { get; set; }
        public static RelayCommand RefreshFilteredParametersCommand { get; set; }
        public static RelayCommand AddProductPhotoCommand { get; set; }
        public static RelayCommand AddLinkPhotoCommand { get; set; }
        public static RelayCommand StarSelectedPhotoCommand { get; set; }
        public static RelayCommand DeleteSelectedPhotoCommand { get; set; }
        public static RelayCommand<string> ChangePageCommand { get; set; }
        public static RelayCommand<string> NavigateToCommand { get; set; }
        public static RelayCommand WindowClosingCommand { get; set; }

        public Page CurrentPage
        {
            get
            {
                dynamic d = pageViewer.CurrentItem;
                return d.page as Page;
            }
        }
        public string CurrentPageName
        {
            get
            {
                dynamic d = pageViewer.CurrentItem;
                return d.name as String;
            }
        }

        private string _statusText;
        public string StatusText
        {
            get { return _statusText; }
            set
            {
                _statusText = value;
                RaisePropertyChanged("StatusText");
            }
        }

        public ObservableCollection<TParam> TFilteredParameters
        {
            get
            {
                if (CurrentAvitoProduct != null)
                {
                    return new ObservableCollection<TParam>(ServiceProxy.GetParams.Where(x => x.CategoryId == CurrentAvitoProduct.TCategory_Id));
                }
                return null;
            }
        }

        public IDataAccessService ServiceProxy { get; set; }


        private CollectionView productViewer;
        private CollectionView pageViewer;
        public EditProductViewModel(IDataAccessService servPxy)
        {
            ServiceProxy = servPxy;
            productViewer = new CollectionView((IEnumerable)ServiceProxy.GetProducts());
            pageViewer = new CollectionView(new[]{
                new {name = "доп.хр-ти", page = (Page) new PageAddProduct(){DataContext = this}},
                new {name = "основные", page = (Page) new PageAdditionals(){DataContext = this}}
            });

            Messenger.Default.Register<AvitoProduct>(this, (ap) =>
            {
                bool isFound = productViewer.MoveCurrentTo(ap);
                if (!isFound)
                {
                    ap.DateInsert = DateTime.Now;
                    ServiceProxy.CreateProduct(ap);
                    var newEntity = ServiceProxy.ChangeTracker.Entries()
                        .Where(x => x.State == EntityState.Added && x.Entity.GetType() == typeof(AvitoProduct))
                        .Select(x => x.Entity);//.FirstOrDefault();

                    productViewer = new CollectionView(newEntity);
                    productViewer.MoveCurrentTo(ap);
                }
                RaisePropertyChanged("TFilteredParameters");
                RaisePropertyChanged("CurrentAvitoProduct");
            });

            WindowClosingCommand = new RelayCommand(CleanAddedEntities);
            RefreshFilteredParametersCommand = new RelayCommand(() => RaisePropertyChanged("TFilteredParameters"));
            AddProductPhotoCommand = new RelayCommand(AddProductPhoto);
            AddLinkPhotoCommand = new RelayCommand(AddLinkPhoto);
            StarSelectedPhotoCommand = new RelayCommand(StarSelectedPhoto);
            DeleteSelectedPhotoCommand = new RelayCommand(DeleteSelectedPhoto);

            ChangePageCommand = new RelayCommand<string>(ChangePage);
            NavigateToCommand = new RelayCommand<string>((url)=>IEHelpers.OpenWebBrowser(url));
            MarkProductCommand = new RelayCommand<AvitoProduct>((ap) => CreatePublicationTask(CurrentAvitoProduct));
            PhotoSelectionChangedCommand = new RelayCommand<AvitoImage>((im) => ImageSelectionChanged(im));
            NextProductCommand = new RelayCommand(NextProduct);
            PrevProductCommand = new RelayCommand(PrevProduct);
            SaveProductCommand = new RelayCommand(SaveProduct);

        }

        private void CleanAddedEntities()
        {
            var hasChanges = ServiceProxy.ChangeTracker.Entries().Count(x => x.State == EntityState.Added) > 0;
            if (hasChanges)
            {
                //TODO: Необходима отладка диалога сохранения нового AvitoProduct
                //var result = MessageBox.Show("Несохраненные товары будут потеряны!", "Был добавлен новый товар", MessageBoxButton.OK, MessageBoxImage.Asterisk);
                //if (result == MessageBoxResult.Yes)
                //{
                    foreach (var entry in ServiceProxy.ChangeTracker.Entries().Where(x => x.State == EntityState.Added))
                    {
                        entry.State = EntityState.Detached;
                    }
                //}
            }

        }

        public void NextProduct()
        {
            if (CurrentAvitoProduct != null && !productViewer.MoveCurrentToNext())
            {
                productViewer.MoveCurrentToLast();
            }

            RaisePropertyChanged("CurrentAvitoProduct");
            RaisePropertyChanged("CurrentAvitoImages");
        }

        public void PrevProduct()
        {
            if (CurrentAvitoProduct != null && !productViewer.MoveCurrentToPrevious())
            {
                productViewer.MoveCurrentToFirst();

            }
            RaisePropertyChanged("CurrentAvitoProduct");
            RaisePropertyChanged("CurrentAvitoImages");
        }

        public AvitoProduct CurrentAvitoProduct
        {
            get
            {
                return productViewer.CurrentItem as AvitoProduct;

            }
        }
        public ObservableCollection<AvitoImage> CurrentAvitoImages
        {
            get
            {
                //var cp = productViewer.CurrentItem as AvitoProduct;
                var cp = CurrentAvitoProduct;
                return new ObservableCollection<AvitoImage>(cp.AvitoImages);

            }
        }


        private void CreatePublicationTask(AvitoProduct ap)
        {
            if (ap != null)
            {
                Messenger.Default.Send<List<AvitoTask>>(new List<AvitoTask>(){new TaskProductUploader(ap){TaskDelay = Settings.Default.PublicationTimeOut}});   
                //StatusText = @"""" + ap.Title.Substring(0, ap.Title.Length > 14 ? 14 : ap.Title.Length) + @""" подготовлен";
                StatusText = "Публикация товара запланирована";
            }
        }

        private AvitoImage _selectedAvitoImage;
        private void ImageSelectionChanged(AvitoImage im)
        {
            _selectedAvitoImage = im;
        }

        private void ChangePage(string pageName)
        {
            if (!pageViewer.MoveCurrentToNext())
            {
                pageViewer.MoveCurrentToFirst();
            }
            else
            {
                pageViewer.MoveCurrentToLast();
            }

            RaisePropertyChanged("CurrentPage");
            RaisePropertyChanged("CurrentPageName");
            RaisePropertyChanged("CurrentAvitoImages");
        }

        private void AddProductPhoto()
        {
            if (CurrentAvitoProduct != null)
            {
                OpenFileDialog openFileDialog1 = new OpenFileDialog();
                openFileDialog1.Filter = "Image files (*.jpeg;*.jpg;*.png;)|*.jpeg;*.jpg;*.png;|All files (*.*)|*.*";
                openFileDialog1.FilterIndex = 1;
                openFileDialog1.Multiselect = false;

                if (openFileDialog1.ShowDialog() == true)
                {
                    var localFileName = Guid.NewGuid() + new FileInfo(openFileDialog1.FileName).Extension;
                    File.Copy(openFileDialog1.FileName, Path.GetFullPath("images/" + Path.GetFileName(localFileName)), true);
                    CurrentAvitoProduct.AvitoImages.Add(new AvitoImage()
                    {
                        LocalFileName = Path.GetFileName(localFileName)
                    });
                    RaisePropertyChanged("CurrentAvitoProduct");
                    RaisePropertyChanged("CurrentAvitoImages");
                }

            }
        }

        private void AddLinkPhoto()
        {
            var link = new InputBox("Ссылка на изображение:").ShowDialog();
            Uri uriResult;
            bool result = Uri.TryCreate(link, UriKind.Absolute, out uriResult);
            if (result)
            {
                CurrentAvitoProduct.AvitoImages.Add(new AvitoImage()
                {
                    RemoteFileUrl = uriResult.ToString()
                });
                RaisePropertyChanged("CurrentAvitoProduct");
                RaisePropertyChanged("CurrentAvitoImages");
            }
        }

        private void DeleteSelectedPhoto()
        {
            if (_selectedAvitoImage!=null)
            {
                ServiceProxy.DeleteImage(_selectedAvitoImage);
                CurrentAvitoImages.Remove(_selectedAvitoImage);
                RaisePropertyChanged("CurrentAvitoProduct");
                RaisePropertyChanged("CurrentAvitoImages");
                StatusText = "Изображение удалено";
            }
            else
            {
                MessageBox.Show("Не выбрано ни одно изображение для удаления!", "Удаление изображения", MessageBoxButton.OK,
                    MessageBoxImage.Asterisk);
            }
        }

        private void StarSelectedPhoto()
        {
            if (_selectedAvitoImage != null)
            {
                foreach (var avitoImage in CurrentAvitoProduct.AvitoImages)
                {
                    avitoImage.IsMainImage = false;
                }
                _selectedAvitoImage.IsMainImage = true;
                RaisePropertyChanged("CurrentAvitoProduct");
                StatusText = "Изображение установлено главным";
            }
            else
            {
                MessageBox.Show("Не выбрано ни одно изображение!", "Главное изображение", MessageBoxButton.OK,
                    MessageBoxImage.Asterisk);
            }
        }

        private void SaveProduct()
        {
            var changesCount =
                ServiceProxy.ChangeTracker.Entries()
                    .Count(x => x.State == EntityState.Modified || x.State == EntityState.Added);
            try
            {
                ServiceProxy.SaveContext();
                StatusText = "Сохранено изменений: " + changesCount;
            }
            catch (Exception ex)
            {
                Logger.Error(ex.InnerException);
                StatusText = "Ошибка сохранения (проверьте заполнение)";
            }
        }



    }
}
